package com.jian.socks5.udp.codec;

import com.jian.socks5.udp.DefaultSocks5UDPPacket;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.socksx.v5.Socks5AddressDecoder;
import io.netty.handler.codec.socksx.v5.Socks5AddressType;

import java.net.InetSocketAddress;
import java.util.List;


/***
 * Socks5 udp报文解码器
 * @author Jian
 * @date 2021.06.21
 */
@ChannelHandler.Sharable
public class Socks5UDPRequestDecoder extends MessageToMessageDecoder<DatagramPacket> {

    @Override
    protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {
        try {
            InetSocketAddress recipient = msg.recipient();
            InetSocketAddress sender = msg.sender();
            ByteBuf in = msg.content();
            short RSV = in.readShort(); // RSV
            byte FRAG = in.readByte(); // FRAG
            Socks5AddressType socks5AddressType = Socks5AddressType.valueOf(in.readByte());
            String dstAddr = Socks5AddressDecoder.DEFAULT.decodeAddress(socks5AddressType, in);
            int dstPort = in.readUnsignedShort();
            int i = in.readableBytes();
            ByteBuf byteBuf = in.readBytes(i);
            DefaultSocks5UDPPacket defaultSocks5UDPPacket = new DefaultSocks5UDPPacket(recipient,sender,RSV, FRAG, socks5AddressType, dstAddr, dstPort, byteBuf);
            out.add(defaultSocks5UDPPacket);
        } catch (Exception e) {
            ctx.fireChannelRead(msg);
        }
    }
}
